package com.zhuanzhuan.hero.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhuanzhuan.hero.user.entity.HeroUserGroupLabelRelation;
import com.zhuanzhuan.hero.user.enums.ExceptionMsgEnum;
import com.zhuanzhuan.hero.user.enums.StateEnum;
import com.zhuanzhuan.hero.user.exception.BusinessException;
import com.zhuanzhuan.hero.user.mapper.HeroUserGroupLabelRelationMapper;
import com.zhuanzhuan.hero.user.service.HeroUserGroupLabelRelationService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * dal Interface:HeroUserGroupLabelRelation
 * @author hanjunjun
 * @date 2024-6-25
 */
@Service
@Slf4j
public class HeroUserGroupLabelRelationServiceImpl
    extends ServiceImpl<HeroUserGroupLabelRelationMapper, HeroUserGroupLabelRelation>
    implements HeroUserGroupLabelRelationService {

    @Override
    public List<HeroUserGroupLabelRelation> listByUid(Long fromUid, Long toUid) {
        HeroUserGroupLabelRelation query = new HeroUserGroupLabelRelation();
        query.setFromUid(fromUid);
        query.setToUid(toUid);
        query.setState(StateEnum.EFFECTIVE.getCode());
        return this.getBaseMapper().select(query);
    }

    @Override
    public List<HeroUserGroupLabelRelation> listByUids(Long fromUid, List<Long> toUids){
        LambdaQueryWrapper<HeroUserGroupLabelRelation> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(HeroUserGroupLabelRelation::getFromUid,fromUid)
            .in(HeroUserGroupLabelRelation::getToUid,toUids)
            .eq(HeroUserGroupLabelRelation::getState,StateEnum.EFFECTIVE.getCode());
        return list(queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void relateGroup(Long fromUid, Long toUid, List<Long> relatedGrouplabelIds) {
        if (fromUid.equals(toUid)) {
            log.info("uid相同，不关联分组");
            throw new BusinessException(ExceptionMsgEnum.PARAM_ERROR);
        }

        //查询db现有的
        List<HeroUserGroupLabelRelation> dbRecords = this.listByUid(fromUid, toUid);
        List<Long> dbLabelIds =
            dbRecords.stream().map(HeroUserGroupLabelRelation::getLabelId).collect(Collectors.toList());

        //提交有，db没有的  新增
        List<Long> insertLabelIds = relatedGrouplabelIds.stream().filter(relateLableId -> !dbLabelIds.contains(relateLableId))
            .collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(insertLabelIds)) {
            //保存新的
            List<HeroUserGroupLabelRelation> insertList = insertLabelIds.stream()
                .map(labelId -> this.buildEntity(fromUid, toUid, labelId))
                .collect(Collectors.toList());
            this.saveBatch(insertList);
        }

        //db有，提交没有的 删除
        List<Long> delIds =
            dbRecords.stream().filter(dbRecord -> !relatedGrouplabelIds.contains(dbRecord.getLabelId()))
                .map(HeroUserGroupLabelRelation::getId).collect(Collectors.toList());
        this.delByIds(delIds);
    }

    @Override
    public void delByUid(Long fromUid, Long toUid) {
        LambdaUpdateWrapper<HeroUserGroupLabelRelation> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(HeroUserGroupLabelRelation::getState, StateEnum.IS_DELETED.getCode())
            .eq(HeroUserGroupLabelRelation::getFromUid, fromUid)
            .eq(HeroUserGroupLabelRelation::getToUid, toUid);
        this.update(updateWrapper);
    }

    @Override
    public void delByLabelIds(List<Long> labelIds) {
        if (CollectionUtils.isNotEmpty(labelIds)) {
            LambdaUpdateWrapper<HeroUserGroupLabelRelation> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(HeroUserGroupLabelRelation::getState, StateEnum.IS_DELETED.getCode())
                .in(HeroUserGroupLabelRelation::getLabelId, labelIds);
            this.update(updateWrapper);
        }
    }

    @Override
    public void delByIds(List<Long> delIds) {
        if (CollectionUtils.isEmpty(delIds)) {
            return;
        }
        LambdaUpdateWrapper<HeroUserGroupLabelRelation> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(HeroUserGroupLabelRelation::getState, StateEnum.IS_DELETED.getCode())
            .in(HeroUserGroupLabelRelation::getId, delIds);
        this.update(updateWrapper);
    }

    private HeroUserGroupLabelRelation buildEntity(Long fromUid, Long toUid, Long labelId) {
        HeroUserGroupLabelRelation entity = new HeroUserGroupLabelRelation();
        entity.setFromUid(fromUid);
        entity.setToUid(toUid);
        entity.setLabelId(labelId);
        entity.setState(StateEnum.EFFECTIVE.getCode());
        entity.setCreateBy(fromUid);
        entity.setUpdateBy(fromUid);
        return entity;
    }
}